package com.synjones.handsetS8;


import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Handler;

import com.synjones.cardutil.util;
import com.techshino.fp.client.Callback;
import com.techshino.fp.client.TcFingerClient;
import com.techshino.fp.entity.FingerResult;
import com.techshino.fp.util.FpConfig;
import com.techshino.fp.util.FpConst;
import com.techshino.fp.util.Logs;
import com.techshino.fp.util.OnConnectListener;
import com.techshino.fp.util.USBUtil;

import java.util.HashMap;
import java.util.Iterator;

/**
 * Created by zhaodianbo on 2017-4-28.
 */
public class S8TcFpUsbModule implements FingerprintReaderInterface {


    Context context;
    Handler outHandler;

    private TcFingerClient mTcFingerClient;
    private USBUtil mUsbUtil;

    private byte[] mTemplateBytes;
    volatile boolean running = false;
    private Bitmap fpBmp;
    FpVerifyResult fpVerifyResult;
    int verifyID=-1;

    public S8TcFpUsbModule(Context context, Handler outHandler) {
        this.context = context;
        this.outHandler = outHandler;
        mUsbUtil = USBUtil.getInstance(context);
        // 设置设备协议
        mUsbUtil.setProtocol(USBUtil.Protocol.TWO);
        mUsbUtil.setConnectListener(new OnConnectListener() {

            @Override
            public void onConnected(TcFingerClient client) {
                sendMsg(MESSAGE_UPDATE_STATUS, "设备连接成功");
                mTcFingerClient = client;
                running=false;
                mTcFingerClient.tcSetEnrollImageCount(1, new Callback() {

                    @Override
                    public void onSuccess(FingerResult result) {
                        sendMsg(MESSAGE_UPDATE_STATUS, "成功！");
                        synchronized (this){
                            notify();
                        }
                    }

                    @Override
                    public void onError(int errorCode) {
                        sendMsg(MESSAGE_UPDATE_STATUS, "errorCode:"
                                + errorCode);
                        synchronized (this){
                            notify();
                        }
                    }
                });
            }

            @Override
            public void onConnectFailed(int code, String msg) {
                sendMsg(MESSAGE_UPDATE_STATUS, msg);
                running=false;
                synchronized (this){
                    notify();
                }
            }
        });
        requestPermission();
    }

    private void sendMsg(int what,Object msg){
        if(outHandler!=null)
            outHandler.obtainMessage(what,msg).sendToTarget();
    }

    @Override
    public void powerOn() {
        if(WtWdPowerUtils.getFingerUSBPower(context)!=1)
            WtWdPowerUtils.setFingerUSBPower(context);
        requestPermission();
    }

    @Override
    public void powerOff() {
        mUsbUtil.disconnectDevice();
        mTcFingerClient=null;
        WtWdPowerUtils.closeFingerUSBPower(context);//关闭
    }

    @Override
    public int open() {
        if(mTcFingerClient!=null) return 0;
        running=true;
        mUsbUtil.connectDevice();
        synchronized (this){
            try {
                wait(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(mTcFingerClient!=null) return 0;
        }
        return -1;
    }


    public void requestPermission() {
        close();
        UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        UsbDevice usbDevice = enumerateDevice(usbManager);
        if(usbDevice==null) return;
        if (usbManager.hasPermission(usbDevice)) {

        } else {
            PendingIntent comm = PendingIntent.getBroadcast(this.context, 0, new Intent("com.techshino.fp.ACTION_USB"), 0);
            usbManager.requestPermission(usbDevice, comm);
        }
    }


    private UsbDevice enumerateDevice(UsbManager usbManager) {
        if(usbManager != null) {
            HashMap deviceList = usbManager.getDeviceList();
            if(!deviceList.isEmpty()) {
                StringBuffer sb = new StringBuffer();
                Iterator var4 = deviceList.values().iterator();

                while(true) {
                    while(var4.hasNext()) {
                        UsbDevice device = (UsbDevice)var4.next();
                        if(device.getVendorId() == 29535 && device.getProductId() == 4865) {
                            return device;
                        } else if(device.getVendorId() == 29535 && device.getProductId() == 4867) {
                            return device;
                        } else if(device.getVendorId() == 29535 && device.getProductId() == 4866) {
                            return device;
                        } else if(device.getVendorId() == 29535 && device.getProductId() == '\uef01') {
                            return device;
                        }
                    }

                    return null;
                }
            }
        }
        return null;
    }

    @Override
    public int close() {
        return 0;
    }

    @Override
    public int cleanFpFeature() {
        return 0;
    }

    @Override
    public FpFeature getFpFeature(boolean showFpImage) {

        if (!isConn())
            return null;
        running=true;
        mTemplateBytes=null;

        //FpConfig.setEnrollDownload(false);
        FpConfig.setEnrollDownload(true);
        FpConfig.setBigPic(true);
        final long start = System.currentTimeMillis();

        mTcFingerClient.tcEnroll(new Callback() {

            @Override
            public void onSuccess(FingerResult result) {
                //sendMsg(MESSAGE_UPDATE_STATUS,"注册成功 " + (System.currentTimeMillis() - start) + "ms");

                byte tmpBuffer[]=result.getTemplate();
                if(tmpBuffer!=null){
                    mTemplateBytes=new byte[tmpBuffer.length];
                    System.arraycopy(tmpBuffer,0,mTemplateBytes,0,mTemplateBytes.length);
                }
                sendMsg(MESSAGE_UPDATE_STATUS,"注册成功,特征length:"
                        + (mTemplateBytes == null ? 0 : mTemplateBytes.length));

                running=false;
                if (result.getImgBytes() == null) {
                    return;
                }
            }

            @Override
            public void onProcess(int code, byte[] img) {
                super.onProcess(code, img);
                enrollProcess(code,img);
            }

            @Override
            public void onError(int errorCode) {
                running=false;
                sendMsg(MESSAGE_UPDATE_STATUS,"失败，errorCode:" + errorCode);
            }
        }, 60000);

        while (running){
            util.mSleep(100);
        }

        if(mTemplateBytes!=null)
            return new FpFeature(fpBmp,mTemplateBytes,"");
        return null;
    }

    @Override
    public int setFpFeature(int toWhere, byte[] data) {

        if (!isConn())
            return -1;
        if (data == null)
            return -2;
        verifyID=toWhere;
       // Logs.i(TAG, "template size:" + mTemplateBytes.length);
        mTcFingerClient.tcSetTemplate(1, data, new Callback() {

            @Override
            public void onSuccess(FingerResult result) {
                sendMsg(MESSAGE_UPDATE_STATUS,  "导入成功！");
            }

            @Override
            public void onError(int errorCode) {
                sendMsg(MESSAGE_UPDATE_STATUS,  "导入失败 errorCode:"
                        + errorCode);
            }
        });
        return 0;
    }

    @Override
    public FpVerifyResult verifyFp(int sThreshold) {

        if (!isConn() || verifyID==-1)
            return null;
        FpConfig.setVerifyDownload(true);
        FpConfig.setBigPic(true);
        final long start  = System.currentTimeMillis();
        running=true;
        fpVerifyResult=null;
        mTcFingerClient.tcVerify(0, new Callback() {

            @Override
            public void onSuccess(FingerResult result) {

                sendMsg(MESSAGE_UPDATE_STATUS,"验证成功 " + (System.currentTimeMillis() - start) + "ms");

                if (result.getImgBytes() != null) {
                    fpBmp = BitmapFactory.decodeByteArray(
                            result.getImgBytes(), 0, result.getImgBytes().length);
                    sendMsg(MSG_WHAT_SHOW_IMG,fpBmp);
                }
                fpVerifyResult=new FpVerifyResult(true,result.getScore(),0);
                running=false;
            }

            @Override
            public void onProcess(int code, byte[] img) {
                super.onProcess(code, img);
                verifyProcess(code);
            }

            @Override
            public void onError(int errorCode) {
                running=false;
                sendMsg(MESSAGE_UPDATE_STATUS,"验证失败 " + (System.currentTimeMillis() - start));
            }
        }, 30000);

        while (running){
            util.mSleep(100);
        }

        return fpVerifyResult;
    }

    @Override
    public void cancel() {
        if (!isConn())
            return;
        mTcFingerClient.tcCancel();
        running=false;
    }

    @Override
    public int calibration() {
        return 0;
    }

    protected void enrollProcess(int code,byte[] img) {
        switch (code) {
            case FpConst.TCY_CAPTUREIMAGE:
                sendMsg(MESSAGE_UPDATE_STATUS,"开始读取指纹图像...");
                break;
            case FpConst.TCY_GETIMAGE:
                if (img == null)
                    return;
                fpBmp= BitmapFactory.decodeByteArray(
                        img, 0, img.length);
                sendMsg(MSG_WHAT_SHOW_IMG,fpBmp);
                break;
            case FpConst.TCY_ENROLL_START:
                sendMsg(MESSAGE_UPDATE_STATUS,"录入开始...");
                break;
            case FpConst.TCY_FAIL:
                sendMsg(MESSAGE_UPDATE_STATUS,"录入失败...");
                break;
            case FpConst.TCY_FLSH:
                sendMsg(MESSAGE_UPDATE_STATUS,"内存不足...");
                break;
            case FpConst.TCY_NOFP:
                sendMsg(MESSAGE_UPDATE_STATUS,"图像质量差...");
                break;
            case FpConst.TCY_MOREIMAGE:
                sendMsg(MESSAGE_UPDATE_STATUS,"继续采集...");
                break;
            default:
                sendMsg(MESSAGE_UPDATE_STATUS,"失败...");
                break;
        }
    }

    protected void verifyProcess(int code) {
        switch (code) {
            case FpConst.TCY_CAPTUREIMAGE:
                sendMsg(MESSAGE_UPDATE_STATUS,"开始读取指纹图像...");
                break;
            case FpConst.TCY_VERIFY_START:
                sendMsg(MESSAGE_UPDATE_STATUS,"认证开始...");
                break;
            case FpConst.TCY_FAIL:
                sendMsg(MESSAGE_UPDATE_STATUS,"失败...");
                break;
            case FpConst.TCY_FLSH:
                sendMsg(MESSAGE_UPDATE_STATUS,"存储出错...");
                break;
            case FpConst.TCY_NOT_EXISTS:
                sendMsg(MESSAGE_UPDATE_STATUS,"标识不存在...");
                break;
            case FpConst.TCY_NOFP:
                sendMsg(MESSAGE_UPDATE_STATUS,"图像质量差...");
                break;
            default:
                sendMsg(MESSAGE_UPDATE_STATUS,"失败...");
                break;
        }
    }

    public boolean isConn() {
        if (mTcFingerClient == null) {
            sendMsg(MESSAGE_UPDATE_STATUS, "设备未连接！");
            return false;
        }
        return true;
    }
}
